﻿using System;
using System.Collections.Generic;
using System.Text;
using com.crawler.common;
using System.Threading;
using System.Text.RegularExpressions;

namespace com.crawler.components
{
    public class BookCraw
    {
        /// <summary>
        /// 站点列表
        /// </summary>
       public  List<BookSiteInfo> m_list = null;

        /// <summary>
        /// 系统配置信息
        /// </summary>
       public  SysConfigInfo m_sys_config = null;

        /// <summary>
        /// 数据处理对象
        /// </summary>
        DBManager m_db_mgr = new DBManager();

        static object m_obj = new object();

        public void CrawlerBookList(object i_site_info)
        {
            lock (m_obj)
            {
                SiteUrl t_site_info = i_site_info as SiteUrl;

                BookSiteInfo t_book_site = null;

                foreach (BookSiteInfo t_book in m_list)
                {
                    if (t_book.SiteId == t_site_info.SiteId)
                    {
                        t_book_site = t_book;
                        break;
                    }
                }

                try
                {
                    string t_html = HttpHelper.GetHttpRequestStringByNUll_Post(t_site_info.Url);

                    string t_book_name = string.Empty;
                    BookInfo t_book = null;
                    MatchCollection t_ma = Regex.Matches(t_html, t_book_site.BookListReg, RegexOptions.IgnoreCase | RegexOptions.Compiled);

                    foreach (Match t_mc in t_ma)
                    {
                        if (string.IsNullOrEmpty(t_mc.Groups[t_book_site.BookUrlRegIndex].Value.ToString().Trim()))
                            continue;
                        t_book_name = t_mc.Groups[t_book_site.BookNameRegIndex].Value.ToString().Trim();
                        if (string.IsNullOrEmpty(t_book_name))
                            continue;
                        t_book = m_db_mgr.GetBookInfoByName(t_book_name);

                        if (t_book == null)
                        {
                            SiteUrl t_book_url = new SiteUrl();

                            t_book_url.Url = CrawlerUtil.GetFullUrl(t_site_info.Url, t_mc.Groups[t_book_site.BookUrlRegIndex].Value.ToString().Trim());
                            t_book_url.BookType = Consts.BookPageType.BookContent;
                            t_book_url.SiteId = t_book_site.SiteId;
                            t_book_url.SiteName = t_book_site.SiteName;
                            t_book_url.ChapterOrder = t_book_site.ChapterOrder;

                            CrawlerBookContent(t_book_site, t_book_url);
                        }


                    }



                }
                catch (Exception ex)
                {
                    LogHelper.Error("搜索小说列表失败" + ex.ToString() + t_site_info.Url);
                }
            }
        }

        private void CrawlerBookContent(BookSiteInfo i_book_site, SiteUrl i_site_url)
        {
            lock (m_obj)
            {
                try
                {
                    string t_html = HttpHelper.GetHttpRequestStringByNUll_Post(i_site_url.Url);

                    Match t_mc = Regex.Match(t_html, i_book_site.BookReg, RegexOptions.IgnoreCase | RegexOptions.Compiled);

                    if (t_mc != null)
                    {
                        BookInfo t_book = ParseBook(t_mc, i_book_site, i_site_url);

                        if (string.IsNullOrEmpty(t_book.BookName))
                        {
                          
                            return;
                        }


                        long t_ret = m_db_mgr.AddBook(t_book);
     
                        if (t_ret > 0)
                        {

                            SiteUrl t_book_url = new SiteUrl();
                            t_book_url.Url = CrawlerUtil.GetFullUrl(i_site_url.Url, t_book.ChapterListUrl.Trim());
                            t_book_url.BookId = t_ret;
                            t_book_url.BookName = t_book.BookName;
                            t_book_url.SiteId = i_site_url.SiteId;
                            t_book_url.ChapterOrder = i_site_url.ChapterOrder;


                            CrawlerBookChapter(i_book_site, t_book_url);
                        }
                    }
                   
                }
                catch (Exception ex)
                {
                    LogHelper.Error("获取小说信息失败" + ex.ToString() + i_site_url.Url);
                }
            }
        }


        private void CrawlerBookChapter(BookSiteInfo i_book_site, SiteUrl i_site_url)
        {
            lock (m_obj)
            {
                try
                {
                    string t_html = HttpHelper.GetHttpRequestStringByNUll_Post(i_site_url.Url);

                    MatchCollection t_ma = Regex.Matches(t_html, i_book_site.ChapterListReg, RegexOptions.IgnoreCase | RegexOptions.Compiled);

                    if (t_ma == null)
                        return;

                    ChapterInfo t_chpater = null;

                    int t_index = 0;

                    int t_total_count = t_ma.Count;


                    List<ChapterInfo> t_list_chapter = new List<ChapterInfo>();

                    DateTime t_update_time_now = DateTime.Now;

                    if (t_ma != null && t_ma.Count > 0)
                    {
                        t_update_time_now = DateTime.Now.AddSeconds(t_ma.Count * -4);
                    }

                    foreach (Match t_mc in t_ma)
                    {
                        t_chpater = new ChapterInfo();

                        if (t_mc.Groups.Count >= i_book_site.ChapterNameRegIndex)
                        {
                            t_chpater.ChapterName = t_mc.Groups[i_book_site.ChapterNameRegIndex].Value.ToString().Trim();
                        }



                        if (t_mc.Groups.Count >= i_book_site.ChapterUrlRegIndex)
                        {
                            t_chpater.ChapterUrl = CrawlerUtil.GetFullUrl(i_site_url.Url, t_mc.Groups[i_book_site.ChapterUrlRegIndex].Value.ToString().Trim());
                        }

                        if (t_mc.Groups.Count >= i_book_site.UpdateTimeRegIndex && i_book_site.UpdateTimeRegIndex != -1)
                        {
                            DateTime t_update_time = DateTime.Now;
                            if (!DateTime.TryParse(t_mc.Groups[i_book_site.UpdateTimeRegIndex].Value.ToString(), out t_update_time))
                                t_update_time = DateTime.Now;
                            t_chpater.UpdateTime = t_update_time;
                        }
                        else
                        {
                            t_index++;
                            //升序
                            if (i_site_url.ChapterOrder == ChapterOrderType.ASC)
                            {
                                t_chpater.UpdateTime = t_update_time_now.AddSeconds(t_index * 3);
                            }
                            else if (i_site_url.ChapterOrder == ChapterOrderType.DESC)
                            {
                                t_chpater.UpdateTime = t_update_time_now.AddSeconds(3 * (t_total_count + 5)).AddSeconds(t_index * (-3));
                            }
                        }

                        if (string.IsNullOrEmpty(t_chpater.ChapterName))
                            continue;

                        t_list_chapter.Add(t_chpater);

                    }

                    if (t_list_chapter.Count > 0)
                    {
                        t_list_chapter.Sort(delegate(ChapterInfo t_a, ChapterInfo t_b)
                        {
                            if (t_a.UpdateTime > t_b.UpdateTime)
                                return 1;
                            else if (t_a.UpdateTime == t_b.UpdateTime)
                                return 0;
                            return -1;
                        });
                    }

                    string t_table_name = "tbchapter";

                   
                    int t_insert_row_count = m_db_mgr.AddChapterList(i_site_url.BookId, i_site_url.BookName, t_list_chapter, t_table_name, i_site_url.SiteId, i_site_url.SiteName);
                }
                catch (Exception ex)
                {
                    LogHelper.Error("获取小说列表失败" + ex.ToString() + i_site_url.Url);
                }
            }
        }


        /// <summary>
        /// 解析小说信息
        /// </summary>
        /// <param name="i_mc"></param>
        /// <param name="i_book_site"></param>
        /// <returns></returns>
        private BookInfo ParseBook(Match i_mc, BookSiteInfo i_book_site, SiteUrl i_site)
        {
            try
            {
                BookInfo t_book = new BookInfo();
                t_book.BookName = i_mc.Groups[i_book_site.BookNameRegIndex2].Value.ToString().Trim().Replace("'", "");
                t_book.AuthorName = i_mc.Groups[i_book_site.AuthorNameRegIndex].Value.ToString().Trim().Replace("'", "");
                t_book.CategoryName = i_mc.Groups[i_book_site.CategoryNameRegIndex].Value.ToString().Trim().Replace("'", "");
                t_book.SubCategoryName = i_mc.Groups[i_book_site.SubCategoryNameRegIndex].Value.ToString().Trim().Replace("'", "");
                t_book.ICONUrl = CrawlerUtil.GetFullUrl(i_site.Url, i_mc.Groups[i_book_site.ICONRegIndex].Value.ToString().Trim()).Replace("'", "");
                t_book.ChapterListUrl = CrawlerUtil.GetFullUrl(i_site.Url, i_mc.Groups[i_book_site.ChapterListUrlIndex].Value.ToString().Trim()).Replace("'", "");
                t_book.Description = CrawlerUtil.FilterContent(i_mc.Groups[i_book_site.DescriptionRegIndex].Value.ToString().Trim());
                t_book.SiteId = i_site.SiteId;
                t_book.SiteName = i_site.SiteName;

                return t_book;
            }
            catch (Exception ex)
            {
                LogHelper.Error("解析小说介绍页失败" + ex.ToString());
                return null;
            }
        }
    }
}
